#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/version.h>

#define DRIVER_NAME "mt7621-gpio-control"
#define GPIO_NUM 22
#define BOOT_DELAY_MS 10000

struct gpio_control_data {
    struct gpio_desc *gpio_desc;
    struct delayed_work boot_complete_work;
    struct miscdevice misc_dev;
    bool gpio_initialized;
    bool boot_completed;
};

static struct gpio_control_data *gpio_data;

static void boot_complete_work_handler(struct work_struct *work)
{
    struct gpio_control_data *data = container_of(work, struct gpio_control_data, boot_complete_work.work);
    
    if (data && data->gpio_desc) {
        gpiod_set_value(data->gpio_desc, 1);
        data->boot_completed = true;
        pr_info("MT7621 GPIO控制: 系统启动完成，GPIO%d设置为高电平\n", GPIO_NUM);
    }
}

static ssize_t gpio_status_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
    struct gpio_control_data *data = gpio_data;
    char status[100];
    int len;
    
    if (!data || !data->gpio_desc)
        return -EFAULT;
    
    len = snprintf(status, sizeof(status), 
                   "GPIO%d状态: 初始化=%s, 启动完成=%s, 当前电平=%d\n",
                   GPIO_NUM,
                   data->gpio_initialized ? "是" : "否",
                   data->boot_completed ? "是" : "否",
                   gpiod_get_value(data->gpio_desc));
    
    if (len <= *ppos)
        return 0;
    
    if (copy_to_user(buf, status + *ppos, len - *ppos))
        return -EFAULT;
    
    *ppos = len;
    return len - *ppos;
}

static ssize_t gpio_control_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
    struct gpio_control_data *data = gpio_data;
    char command[10];
    
    if (!data || !data->gpio_desc)
        return -EFAULT;
    
    if (count > sizeof(command) - 1)
        return -EINVAL;
    
    if (copy_from_user(command, buf, count))
        return -EFAULT;
    
    command[count] = '\0';
    
    if (strncmp(command, "high", 4) == 0) {
        gpiod_set_value(data->gpio_desc, 1);
        pr_info("MT7621 GPIO控制: 用户空间设置GPIO%d为高电平\n", GPIO_NUM);
    } else if (strncmp(command, "low", 3) == 0) {
        gpiod_set_value(data->gpio_desc, 0);
        pr_info("MT7621 GPIO控制: 用户空间设置GPIO%d为低电平\n", GPIO_NUM);
    } else if (strncmp(command, "toggle", 6) == 0) {
        int current_value = gpiod_get_value(data->gpio_desc);
        gpiod_set_value(data->gpio_desc, !current_value);
        pr_info("MT7621 GPIO控制: 切换GPIO%d电平为%d\n", GPIO_NUM, !current_value);
    } else {
        return -EINVAL;
    }
    
    return count;
}

static const struct file_operations gpio_fops = {
    .owner = THIS_MODULE,
    .read = gpio_status_read,
    .write = gpio_control_write,
};

static int gpio_control_probe(struct platform_device *pdev)
{
    struct device *dev = &pdev->dev;
    struct gpio_control_data *data;
    int ret;
    
    pr_info("MT7621 GPIO控制驱动: 开始加载\n");
    
    data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    if (!data)
        return -ENOMEM;
    
    data->gpio_desc = devm_gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
    if (IS_ERR(data->gpio_desc)) {
        dev_err(dev, "无法获取GPIO%d: %ld\n", GPIO_NUM, PTR_ERR(data->gpio_desc));
        return PTR_ERR(data->gpio_desc);
    }
    
    gpiod_set_value(data->gpio_desc, 0);
    data->gpio_initialized = true;
    data->boot_completed = false;
    
    dev_info(dev, "MT7621 GPIO控制: 启动阶段设置GPIO%d为低电平\n", GPIO_NUM);
    
    INIT_DELAYED_WORK(&data->boot_complete_work, boot_complete_work_handler);
    
    data->misc_dev.minor = MISC_DYNAMIC_MINOR;
    data->misc_dev.name = "mt7621-gpio-control";
    data->misc_dev.fops = &gpio_fops;
    data->misc_dev.parent = dev;
    
    ret = misc_register(&data->misc_dev);
    if (ret) {
        dev_err(dev, "无法注册misc设备: %d\n", ret);
        return ret;
    }
    
    gpio_data = data;
    platform_set_drvdata(pdev, data);
    
    schedule_delayed_work(&data->boot_complete_work, msecs_to_jiffies(BOOT_DELAY_MS));
    
    dev_info(dev, "MT7621 GPIO控制驱动: 加载成功，将在%d毫秒后设置GPIO为高电平\n", BOOT_DELAY_MS);
    return 0;
}

static int gpio_control_remove(struct platform_device *pdev)
{
    struct gpio_control_data *data = platform_get_drvdata(pdev);
    
    if (data) {
        cancel_delayed_work_sync(&data->boot_complete_work);
        misc_deregister(&data->misc_dev);
        
        if (data->gpio_desc) {
            gpiod_set_value(data->gpio_desc, 0);
        }
    }
    
    pr_info("MT7621 GPIO控制驱动: 已卸载\n");
    return 0;
}

static const struct of_device_id gpio_control_of_match[] = {
    { .compatible = "mediatek,mt7621-gpio-control" },
    { }
};
MODULE_DEVICE_TABLE(of, gpio_control_of_match);

static struct platform_driver gpio_control_driver = {
    .probe = gpio_control_probe,
    .remove = gpio_control_remove,
    .driver = {
        .name = DRIVER_NAME,
        .of_match_table = gpio_control_of_match,
        .owner = THIS_MODULE,
    },
};

static int __init gpio_control_init_early(void)
{
    int ret;
    
    pr_info("MT7621 GPIO控制驱动: 早期初始化开始\n");
    
    ret = platform_driver_register(&gpio_control_driver);
    if (ret) {
        pr_err("MT7621 GPIO控制驱动: 平台驱动注册失败: %d\n", ret);
        return ret;
    }
    
    pr_info("MT7621 GPIO控制驱动: 早期初始化完成\n");
    return 0;
}
arch_initcall(gpio_control_init_early);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("OpenWrt Developer");
MODULE_DESCRIPTION("MT7621 GPIO Control Driver");
MODULE_VERSION("1.0");
